package server;

import com.mysql.jdbc.exceptions.MySQLIntegrityConstraintViolationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
import java.util.Vector;

/**
 * Created by IntelliJ IDEA.
 * User: sam
 * Date: 25/06/12
 * Time: 19:44
 * To change this template use File | Settings | File Templates.
 */

public class GenreServlet extends MFHttpServlet {

    String UPLOAD_LOCATION = "/home/sam/mf_server_dump/music_finder_uploads"+File.separator;
    private StringBuilder strResp;
    private int numUploads = 0; //OUCH!!! Only bit of domain/meta data we store at class level... hack
    private Connection connection;
    private Document requestXML;
    private Properties props;

    String genresSQL = "";

    public GenreServlet(){

    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        System.out.println("GenreServlet.doPost()"+"\n");

        ServletContext servletContext = request.getSession().getServletContext();

        props = (Properties) servletContext.getAttribute("properties");

        connection = (Connection) getServletContext().getAttribute("db_connection");

        doGenreRequest(request, response);

        connection = null;
    }

    public void doGenreRequest(HttpServletRequest request, HttpServletResponse response){

        System.out.println("doGenreRequest()");

        /**
         *  Request:
         *
         * <MFRequest>
         *         <Request type='Catagories' data=''>
         *  </MFRequest>
         */

        // getGenres() has populated global StringBuilder used in write()

        int userRepository = Integer.parseInt(request.getSession().getAttribute("userRepository").toString());

        StringBuilder genresListOnly = getGenres(userRepository);//new StringBuilder(getGenres(userRepository).toString());

        StringBuilder strResp = new StringBuilder();

        strResp.append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
        strResp.append("<MFResponse>\n");
        strResp.append("<Response type='Catagories'>\n");
        strResp.append(genresListOnly.toString());
        strResp.append("</Response>\n");
        strResp.append("</MFResponse>\n");

        write(response, strResp);

    }



    public void doAddNewGenre(HttpServletRequest request, HttpServletResponse response) /*throws RuntimeException*/ {
        System.out.println("doAddNewGenre()");

        NodeList nList = requestXML.getElementsByTagName("Genre");
        Node nNode = nList.item(0);
        Element eElement = (Element) nNode;

        // TODO check if genre already exists and add repos ID to mf_genres
        String query = new String();

        HttpSession session = request.getSession();

        int repository = Integer.parseInt(session.getAttribute("userRepository").toString());

        /**
         * INSERT INTO musicfinder.mf_genres (name, description, repository) VALUES ('Rock', 'cool', 1) WHERE mf_genres.name NOT !='Rock';
         *
         * With full BLOB or TEXT without the length value, MySQL is unable to guarantee the uniqueness
         * of the column as it’s of variable and dynamic size. So, when using BLOB or TEXT types as index,
         * the value of N must be supplied so that MySQL can determine the key length. However,
         * MySQL doesn’t support limit on TEXT or BLOB. TEXT(88) simply won’t work.
         *
         * ALTER TABLE mf_genres CHANGE name name VARCHAR(255);
         *
         * Adding unique constraint below means we dont have to do condition where not exists, insert. as
         * attempting to insert with unique constraint will fail, if it violates it:
         *
         * ALTER TABLE mf_genres ADD CONSTRAINT uc_genre UNIQUE (name,repository);
         *
         * .. so now we get (e.g. trying to re-add 'Rock' genre):
         *
         * Duplicate entry 'Rock-1' for key 'uc_genre'
         * com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException:
         * Duplicate entry 'Rock-1' for key 'uc_genre'
         *
         * import com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException;
         *
         * MySQL DUAL Conditional insert:
         *
         * http://stackoverflow.com/questions/913841/mysql-conditional-insert
         */

        query += "INSERT INTO musicfinder.mf_genres (name, description, repository) VALUES (";

        nNode = nList.item(0);

        String failureMsg = "";
        String newGenre = "";
        String genreDescription = "";

        if (nNode.getNodeType() == Node.ELEMENT_NODE) {
            eElement = (Element) nNode;
            eElement.normalize();
            newGenre = eElement.getAttribute("name");
            genreDescription = eElement.getAttribute("description");

            query += "'" + newGenre + "', '" + genreDescription+"', "+repository+");";

            //query += ") WHERE mf_genres.name NOT ='"+newGenre+"';";
        }

        System.out.println(query);

        try {
            //Class.forName("com.mysql.jdbc.Driver");  //registering the jdbc driver here

            //db_con = DriverManager.getConnection(db_url, db_user, db_pwd);
            Statement db_st = connection.createStatement();
            int tmp = db_st.executeUpdate(query);


        }
        catch( MySQLIntegrityConstraintViolationException e3)  {    // actually caught by SQL exception, so move it here to be specific
            System.out.println("MySQLIntegrityConstraintViolationException "+e3.getMessage());
            e3.printStackTrace();
            writeErrorResponse(request, response, "GENRE_CONFLICT");
            //throw new RuntimeException("GenreAlreadyExists");
        } catch (SQLException e2) {  // Dont know why this is SQL exception and not caught by MySQLIntegrityConstraintViolationException

            System.out.println("SQLException "+e2.getMessage());

            if(e2.getMessage().contains("Duplicate entry")) {
                writeErrorResponse(request, response, "GENRE_CONFLICT");
            }

            System.out.println(e2.getMessage());
            e2.printStackTrace();
        }
        finally {
            if(failureMsg.equals("")){

                String username = session.getAttribute("username").toString();

                String msg = username + " has added a new genre '" + newGenre + "' ("+genreDescription+").";

                notifyUsersOfActivity(msg, request.getSession(false));

                doGenreRequest(request, response);
            }
        }
    }

    private void notifyUsersOfAddedGenre(String newGenre, String genreDesc, HttpSession serverSession) {

        //Vector<String> emailAddresses = getEmailAddresses(serverSession);

        //String username = serverSession.getAttribute("username").toString();

        //String msg = username + " has added genre '" + newGenre + "' ("+genreDesc+")";

        //notifyUsersOfActivity(msg,serverSession);
    }
}
